package net.xujialiang.XTestRPA.Service.RPA;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import net.xujialiang.XTestRPA.Entity.Env.Relations.XRPAEnvAndEnvTag;
import net.xujialiang.XTestRPA.Entity.Env.XRPAEnv;
import net.xujialiang.XTestRPA.Entity.RPA.Relations.XRPATaskAndTag;
import net.xujialiang.XTestRPA.Entity.RPA.XRPATask;
import net.xujialiang.XTestRPA.Entity.Tenant.XRPATenant;
import net.xujialiang.XTestRPA.Repository.RPA.RPATaskAndTagRepository;
import net.xujialiang.XTestRPA.Repository.RPA.RPATaskRepository;
import net.xujialiang.XTestRPA.Repository.Tenant.TenantRepository;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.*;

@Service
public class XRPATaskService {
    @Autowired
    RPATaskRepository taskRepository;
    @Autowired
    RPATaskAndTagRepository taskAndTagRepository;
    @Autowired
    TenantRepository tenantRepository;
    @Autowired
    XRPAPointService pointService;

    public void createTask(Map<String, Object> reqData, String createAccount, String ttc) throws Exception {
        String taskName = (String) reqData.getOrDefault("taskName", "");
        String groupId = (String) reqData.getOrDefault("groupId", "");
        if(groupId.equals("")){
            throw new Exception("未选择分组");
        }
        ArrayList tagIDs = (ArrayList) reqData.getOrDefault("tagIDs", new ArrayList());
        String tagIDStr = "";
        for (Object tagID:tagIDs) {
            tagIDStr = tagIDStr + tagID.toString() + ",";
        }
        tagIDStr = tagIDStr.substring(0, tagIDStr.length()-1);
        String taskData = (String) reqData.getOrDefault("taskData", "");
        String mark = (String) reqData.getOrDefault("mark", "");
        int costPoint = (int) reqData.getOrDefault("costPoint", 10);
        XRPATask entity = XRPATask.builder()
                .taskID(UUID.randomUUID().toString())
                .taskName(taskName)
                .groupID(groupId)
                .tagIDs(tagIDStr)
                .taskData(taskData)
                .ttc(ttc)
                .createAccount(createAccount)
                .createTime(new Timestamp(System.currentTimeMillis()))
                .costPoint(costPoint)
                .mark(mark)
                .build();
        taskRepository.save(entity);

        // 标签关联关系
        List<XRPATaskAndTag> tags = new ArrayList<>();
        for (Object tagId: tagIDs) {
            XRPATaskAndTag e = XRPATaskAndTag.builder().taskID(entity.getTaskID()).tagID((String) tagId).build();
            tags.add(e);
        }
        List<XRPATaskAndTag> existsData = taskAndTagRepository.findAllByTaskID(entity.getTaskID());
        taskAndTagRepository.deleteAll(existsData);
        taskAndTagRepository.saveAll(tags);
    }

    /**
     * 删除任务
     * @param id 任务ID
     * @param ttc 租户
     * @throws Exception
     */
    public void delete(int id, String ttc) throws Exception {
        Optional<XRPATask> ret = taskRepository.findById(id);
        if(ret.isEmpty()){
            throw new Exception("未查询到");
        }else{
            XRPATask entity = ret.get();
            // 判断是否是该分组所在租户
            if(entity.getTtc().equals(ttc)){
                // 删除ENVTAG关联关系
                List<XRPATaskAndTag> relations = taskAndTagRepository.findAllByTaskID(entity.getTaskID());
                taskAndTagRepository.deleteAll(relations);
                taskRepository.delete(entity);
            }else{
                throw new Exception("无权限操作");
            }
        }
    }

    public XRPATask fetchById(Integer id, String ttc) throws Exception {
        Optional<XRPATask> ret = taskRepository.findById(id);
        if(ret.isEmpty()){
            throw new Exception("未查询到任务");
        }else{
            XRPATask entity = ret.get();
            return entity;
        }
    }

    /**
     * 分页查询任务
     * @param groupId 分组ID
     * @param tagIds 标签IDs
     * @param ttc 租户
     * @param page 页码
     * @param pageSize 页面数据量
     * @return
     * @throws Exception
     */
    public Map<String, Object> fetchByPage(String groupId, String taskName,  List<String> tagIds, String ttc, int page, int pageSize) throws Exception {

        PageRequest pr =  PageRequest.of(page,pageSize);

//        List<XRPATask> list;
//        Page pageData;
//        if(groupId.length()>0 && tagIds.size()>0){
//            // 根据GroupId和TagIds查询
//            pageData = taskRepository.findTaskIDsByGroupIDAndTagIDS(groupId, tagIds, ttc, pr);
//            list = (List<XRPATask>) taskRepository.findAllById(pageData.getContent());
//        }else if(groupId.length()>0 && tagIds.size()<=0){
//            // 根据GroupId查询
//            pageData = taskRepository.findTaskIDsByGroupID(groupId, ttc, pr);
//            list = (List<XRPATask>) taskRepository.findAllById(pageData.getContent());
//        }else if(groupId.length()<=0 && tagIds.size()>0){
//            // 根据tagIds查询
//            pageData = taskRepository.findTaskIDsByTagIDS(tagIds, ttc, pr);
//            list = (List<XRPATask>) taskRepository.findAllById(pageData.getContent());
//        }else{
//            // 查询全部
//            pageData = taskRepository.findByTtc(ttc, pr);
//            list = pageData.getContent();
//        }

        if(tagIds.size() == 0){
            tagIds = null;
        }
        if(groupId.equals("")){
            groupId = null;
        }
        if(taskName.equals("")){
            taskName = null;
        }
        Page<XRPATask> pageData =  taskRepository.findByTaskNameAndGroupIdAndByTagIds(groupId, taskName, tagIds, ttc, pr);
//        List<XRPATask> list = (List<XRPATask>) taskRepository.findAllById(pageData.getContent());;
        Map<String, Object> ret = new LinkedHashMap<>();
        ret.put("totalPages", pageData.getTotalPages());
        ret.put("totalCount", pageData.getTotalElements());
        ret.put("page", page);
        ret.put("pageSize", pageSize);
        ret.put("list", pageData.getContent());
        return ret;
    }

    /**
     * 修改RPA数据
     * @param reqData 数据
     * @param ttc 租户
     * @throws Exception
     */
    public void update(Map<String, Object> reqData, String ttc) throws Exception {
        Integer id = (Integer) reqData.get("id");
        Optional<XRPATask> ret = taskRepository.findById(id);
        if(ret.isEmpty()){
            throw new Exception("未查询到任务信息");
        }else{
            XRPATask entity = ret.get();
            if(entity.getTtc().equals(ttc)){
                String taskName = (String) reqData.get("taskName");
                if(taskName != null){
                    entity.setTaskName(taskName);
                }
                String groupId = (String) reqData.get("groupId");
                if(groupId != null){
                    entity.setGroupID(groupId);
                }
                ArrayList tagIDs = (ArrayList) reqData.get("tagIDs");
                if(tagIDs!=null && tagIDs.size()>0){
                    String tagIDStr = "";
                    for (Object tagID:tagIDs) {
                        tagIDStr = tagIDStr + tagID.toString() + ",";
                    }
                    tagIDStr = tagIDStr.substring(0, tagIDStr.length()-1);
                    entity.setTagIDs(tagIDStr);
                }

                String taskData = (String) reqData.get("taskData");
                if(taskData != null){
                    entity.setTaskData(taskData);
                }
                String mark = (String) reqData.get("mark");
                if(mark != null){
                    entity.setMark(mark);
                }
                int costPoint = (int) reqData.getOrDefault("costPoint", 10);
                entity.setCostPoint(costPoint);
                taskRepository.save(entity);

                // 创建标签的关联关系
                List<XRPATaskAndTag> tags = new ArrayList<>();
                for (Object tagId: tagIDs) {
                    XRPATaskAndTag e = XRPATaskAndTag.builder().taskID(entity.getTaskID()).tagID((String) tagId).build();
                    tags.add(e);
                }
                List<XRPATaskAndTag> existsData = taskAndTagRepository.findAllByTaskID(entity.getTaskID());
                taskAndTagRepository.deleteAll(existsData);
                taskAndTagRepository.saveAll(tags);

            }else{
                throw new Exception("无权限操作");
            }
        }
    }

    /**
     * 修改RPA任务流程数据
     * @param id 任务ID
     * @param taskData 任务数据
     * @param ttc 租户
     * @throws Exception
     */
    public void updateTaskData(Integer id,  String taskData, Integer costPoint, String ttc) throws Exception {
        Optional<XRPATask> ret = taskRepository.findById(id);
        if(ret.isEmpty()){
            throw new Exception("未查询到任务信息");
        }else{
            XRPATask entity = ret.get();
            if(entity.getTtc().equals(ttc)){
                entity.setTaskData(taskData);
                entity.setCostPoint(costPoint);
                taskRepository.save(entity);
            }else{
                throw new Exception("无权限操作");
            }
        }
    }

    /**
     * 修改排序
     * @param newOrders 新的排序
     * @param ttc 租户号
     * @throws Exception
     */
    public void updateTaskOrder(Map<Integer, Integer> newOrders, String ttc) throws Exception {
        Object[] ids = newOrders.keySet().toArray();
        Arrays.stream(ids).mapToInt(t-> (int) t);
        ArrayList<Integer> list = new ArrayList(Arrays.asList(ids));

        List<XRPATask> envs = (List<XRPATask>) taskRepository.findAllById(list);

        boolean noPermission = false;
        for (int i = 0; i < envs.size(); i++) {
            XRPATask task = envs.get(i);
            if(task.getTtc().equals(ttc)){
                Integer newOrder = newOrders.get(task.getId());
                task.setMOrder(newOrder);
            }else{
                noPermission= true;
            }
        }
        if(noPermission) {
            throw new Exception("无权限操作");
        }else{
            taskRepository.saveAll(envs);
        }
    }

    /**
     * 导入数据
     * @param multipartFile json文件
     * @param groupId 分组ID
     * @param ttc 租户
     * @throws Exception
     */
    public void importData(MultipartFile multipartFile, String groupId, String ttc) throws Exception {
        // TODO: 自动创建标签
        // 获取原始名字
        String fileName = multipartFile.getOriginalFilename();
        // 获取后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //先将.json文件转为字符串类型
        UUID uuid = UUID.randomUUID();
        File file = new File("./tmp/"+ uuid+".json");
        //将MultipartFile类型转换为File类型
        FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),file);
        String jsonString = FileUtils.readFileToString(file, "UTF-8");

        //如果是json或者txt文件
        if (".json".equals(suffixName)) {
            //再将json字符串转为实体类
            Type listType = new TypeToken<ArrayList<XRPATask>>(){}.getType();
            List<XRPATask> envList = new Gson().fromJson(jsonString, listType);
            for (XRPATask entity : envList) {
                entity.setTaskID(UUID.randomUUID().toString());
                entity.setId(null);
                entity.setGroupID(groupId);
                entity.setTtc(ttc);
            }

            taskRepository.saveAll(envList);
        } else {
            throw new Exception("请上传正确格式的json");
        }
    }

    /**
     * 导出数据
     * @param reqData 请求数据
     * @param ttc 租户
     * @return
     */
    public List<XRPATask> exportData(Map<String, Object> reqData, String ttc){
        List<Integer> envIds = (List<Integer>) reqData.get("ids");
        if(envIds != null && envIds.size()>0){
            // 导出指定的环境
            return (List<XRPATask>) taskRepository.findAllById(envIds);
        }else{
            //导出所有环境
            return taskRepository.findAllByTtc(ttc);
        }
    }

    /**
     * 执行RPA流程
     * @param id 任务ID
     * @param ttc 租户
     * @throws Exception
     */
    public void executeTask(Integer id, Integer costPoint, String ttc, String operator) throws Exception {
        Optional<XRPATask> ret = taskRepository.findById(id);
        if(ret.isEmpty()){
            throw new Exception("未查询到任务信息");
        }else{
            XRPATask entity = ret.get();
            if(entity.getTtc().equals(ttc)){
                // 计算点数是否够
                Optional<XRPATenant> ret2 = tenantRepository.findByTtc(ttc);
                XRPATenant tenantInfo = ret2.get();
                long diff = tenantInfo.getRpapoints() - costPoint;
                if(diff >=0){
                    taskRepository.save(entity);
                    tenantInfo.setRpapoints(diff);
                    tenantRepository.save(tenantInfo);
                    // 点数消费记录
                    pointService.costPoint(entity.getTaskID(),entity.getTaskName(),costPoint, "消费", operator, ttc);
                }else{
                    throw new Exception("执行失败, RPA点数不足, 请在我的账单中兑换RPA点数。");
                }
            }else{
                throw new Exception("无权限操作");
            }
        }
    }
}